package com.liu.redis.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @Author QS.Liu
 * @date 2020/5/17/19:27
 */
public class redisUtils {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * @return boolean
     * @Author QS.L
     * @Description 指定缓存失效时间
     * @Date 2020/5/17 21:45
     * @Param [key, time] 键 ，时间
     */
    public boolean expire(String key, long time) {
        try {
            redisTemplate.expire(key, time, TimeUnit.SECONDS);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @return long
     * @Author QS.L
     * @Description 获取过期时间
     * @Date 2020/5/17 21:47
     * @Param [key] 键
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key);
    }

    /**
     * @return boolean
     * @Author QS.L
     * @Description 判断key是否存在
     * @Date 2020/5/17 21:51
     * @Param [key]
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * @return void
     * @Author QS.L
     * @Description 删除缓存  可以删除多个
     * @Date 2020/5/17 21:55
     * @Param [key] 可以删除多个key
     */
    public void delete(String... key) {
        try {
            if (key != null && key.length > 0) {
                if (key.length == 1) {
                    redisTemplate.delete(key[0]);
                }
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * @Description 获取值
     *
     **/
    //===========================================String=============================================

    /**
     * @return Object
     * @Author QS.L
     * @Description 普通String缓存获取
     * @Date 2020/5/17 22:05
     * @Param [key]
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * @return boolean
     * @Author QS.L
     * @Description 普通缓存存入
     * @Date 2020/5/17 22:13
     * @Param [key, value]
     */
    public boolean set(String key, Object value) {
        try {
            if (key != null && value != null) {
                redisTemplate.opsForValue().set(key, value);
                return true;
            } else {
                throw new RuntimeException("存储键值为空");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @return boolean
     * @Author QS.L
     * @Description 存储缓存并设置过期时间
     * @Date 2020/5/17 22:20
     * @Param [key, value, time] 如果time<0 将设置无期限
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (key != null && value != null && time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
                return true;
            } else if (time <= 0) {
                redisTemplate.opsForValue().set(key, value);
            } else {
                throw new RuntimeException("存储键值为空");
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @return long
     * @Author QS.L
     * @Description 递增
     * @Date 2020/5/17 22:26
     * @Param [key, delta]
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子需要大于0");
        } else {
            return redisTemplate.opsForValue().increment(key, delta);
        }
    }

    /**
     * @return long
     * @Author QS.L
     * @Description 递减
     * @Date 2020/5/17 22:26
     * @Param [key, delta]
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子需要大于0");
        } else {
            return redisTemplate.opsForValue().decrement(key, delta);
        }
    }

    //=========================================== map =============================================
    //hset  单个值 hmset 多个值

    /**
     * @return java.lang.Object
     * @Description hget key-[item-value] 获取value
     * @Date 2020/5/17 22:36
     * @Param [key, item]
     */
    @SuppressWarnings("unchecked")
    public Object hget(String key, String itemKey) {
        return redisTemplate.opsForHash().get(key, itemKey);
    }

    /**
     * @return java.util.Map<java.lang.Object   ,   java.lang.Object>
     * @Description hmget 获取hashkey对应的键值
     * @Date 2020/5/17 22:43
     * @Param [key]
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * @return boolean
     * @Description hmset 缓存map
     * @Date 2020/5/17 22:56
     * @Param [key, map]
     */
    public boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @return boolean
     * @Description hmset 缓存map 并且设置过期时间
     * @Date 2020/5/17 23:04
     * @Param [key, map, time]
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @return boolean
     * @Description hset 像hash表中存储数据，如果不存在则创建
     * @Date 2020/5/17 23:06
     * @Param [key, itemKey, value]
     */
    public boolean hset(String key, String itemKey, Object value) {
        try {
            redisTemplate.opsForHash().put(key, itemKey, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @return boolean
     * @Description hset 存储hash数据并且设置缓存
     * @Date 2020/5/17 23:17
     * @Param [key, itemKey, value, time]
     */
    public boolean hset(String key, String itemKey, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, itemKey, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @return void
     * @Description hdel
     * @Date 2020/5/17 23:41
     * @Param [key, itemKey]
     */
    public void hdel(String key, String... itemKey) {
        redisTemplate.opsForHash().delete(key, itemKey);
    }

    /**
     * @return boolean
     * @Description hasHashKey判断是否含有值
     * @Date 2020/5/17 23:46
     * @Param [key, itemKey]
     */
    public boolean hasHashKey(String key, String itemKey) {
        return redisTemplate.opsForHash().hasKey(key, itemKey);
    }

    /**
     * @return double
     * @Description hincr递增
     * @Date 2020/5/17 23:50
     * @Param [key, itemKey, num]
     */
    public double hincr(String key, String itemKey, double num) {
        if (num < 0) {
            throw new RuntimeException("递增因子需要大于0");
        }
        return redisTemplate.opsForHash().increment(key, itemKey, num);
    }

    /**
     * @return double
     * @Description hdecr 递减
     * @Date 2020/5/17 23:50
     * @Param [key, itemKey, num]
     */
    public double hdecr(String key, String itemKey, double num) {
        if (num < 0) {
            throw new RuntimeException("递增因子需要大于0");
        }
        return redisTemplate.opsForHash().increment(key, itemKey, -num);
    }
    //=========================================== set =============================================

    /**
     * @return java.util.Set<java.lang.Object>
     * @Description sGet 获取set中的所有值
     * @Date 2020/5/17 23:57
     * @Param [key]
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @return boolean
     * @Description sHashKey 判断值是否存在
     * @Date 2020/5/18 0:02
     * @Param [key, value]
     */
    public boolean sHashKey(String key, Object value) {
        try {
            redisTemplate.opsForSet().isMember(key,value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * @Description sSet 存储set
     * @Date 2020/5/18 0:16 
     * @Param [key, values]
     * @return long
    */
    public long sSet(String key,Object... values){
        try {
            return redisTemplate.opsForSet().add(key,values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * @Description sSet 存储set
     * @Date 2020/5/18 0:16
     * @Param [key, values]
     * @return long
     */
    public long sSetTime(String key,Long time,Object... values){
        try {
            Long l=redisTemplate.opsForSet().add(key,values);
            if (time>0)expire(key,time);
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * @Description sGetSetSize 获取set长度
     * @Date 2020/5/18 0:21
     * @Param [key]
     * @return long
    */
    public long sGetSetSize(String key){
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * @Description sRemove
     * @Date 2020/5/18 0:25
     * @Param [key, values]
     * @return long
    */
    public long sRemove(String key,Object... values){
        try {
            return redisTemplate.opsForSet().remove(key,values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    //=========================================== list =============================================
    //=========================================== Z-set =============================================
}
